home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
program
/
tjgold.zip
/
INSTALL.004
/
FGUSER04.TXT
< prev
next >
Wrap
Text File
|
1995-05-29
|
49KB
|
1,155 lines
Screen & Window Management
"The possession of gold has ruined fewer men than the lack of it."
Thomas Bailey Aldrich, 1903
Introduction
To put it bluntly, Turbo Pascal's writeln just isn't powerful
enough for today's sophisticated applications. That's why Gold
includes GOLDFAST and GOLDWIN. These units provide a powerful set
of screen and window management routines, including the following:
A family of flexible screen writing procedures making it easy
to write at a specific location, write right-justified, write text
automatically centered between two coordinates, etc. Routines to
draw boxes and lines in a variety of shapes and sizes. The line
drawing functions can automatically join-up with other lines
already on display. 25, 43 and 50 line displays are supported.
Virtual screens which can be created, written to and then moved to
the visible screen for viewing. Multiple overlapping windows which
can be partially dragged off screen, tiled, zoomed and stretched.
Gold can write to partially or fully obscure Windows as well as the
underlying background. All or part of the screen can be saved and
restored with a variety of special effects. Routines to read the
text or attribute directly from a screen or window. Functions to
change the cursor shape and position. A set of boilerplate windows
to prompt the user to select actions such as OK or Cancel, Yes or
No, Live or Die, etc.
TTT 5 Users -- the windows management functions have been
totally re-written for Gold. The old-style MkWin and RmWin
procedures are still supported, but they don't offer any new
functionality and are primarily offered for backward compatibility.
To really leverage the power of Gold, you should change over to the
new Winxxx procedures.
Understanding the Active Target
If you don't have any windows or virtual screens, life is
easy; every time you call one of the screen writing procedures
(such as WriteAT) the text is written to the screen for all to see.
No problem. However, if you have windows displayed or virtual
screens created, Gold has to know where the text should be written.
Remember, you can write to any window, virtual screen, or the
visible screen. For example, on a desktop application, you might
want to write some help text in window 1, display a list in window
2, and perhaps write the current time to the background. Rather
than force you to specify the target item with every procedure
call, Gold uses the notion of active target. That is, at any one
time either the visible screen, a virtual screen, or a window will
have the active target, and Gold will direct all screen writing
activity to that target. If you write some text which doesn't
appear, check the active target -- you might be writing to a
virtual screen or an obscured window.
The following procedures support target management:
ActivateWindow(Win:word);
When you create a window, a window number or handle is
returned. This procedure sets the target to the specified window.
If the specified window does not exist, this procedure will be
ignored.
ActivateTopWindow;
Makes the top-most window the target. If there are no windows,
this procedure will be ignored.
ActivateVirtualScreen(Page:word);
Sets the target to the specified virtual screen. If the
virtual screen does not exist, this procedure will be ignored.
ActivateVisibleScreen;
Sets the target to be the main screen. Gold will ignore all
active windows and will write directly to the display. If there are
windows displayed, you should use the next function.
ActivateBackground;
Use this function when windows are displayed and you want to write
text behind the windows, i.e. to the background. If no windows are
on display, this procedure is ignored.
General Purpose String Writing
The Write Procedures
The following GOLDFAST functions will help you to quickly and
easily write wherever you want:
WritePlain(X,Y:byte; Str:string);
WriteAT(X,Y,FB:byte; Str:string);
WriteCol(Col,Row:byte; Str:string);
WriteClick(X,Y,FB:byte;Str:string);
WriteCenter(Y,FB:byte;Str:string);
WriteMiddle(X,FB:byte;Str:string);
WriteBetween(X1,X2,Y,FB:byte;Str:string);
WriteRight(X,Y,FB:byte;Str:string);
WriteVert(X,Y,FB:byte;Str:string);
The procedure names are self-explanatory, but you can refer to
the Reference Manual or the on-line help for a full description of
each procedure. Note that Gold does not move the cursor during
screen writes.
If you specify a color attribute (FB) of UseTint (defined in
GOLDATTR) with any of the screen writing procedures Gold will use
the existing display attribute, i.e. written text will assume the
color of the underlying screen or window.
TTT 5 Users -- all functions which accept a color use a
combined color attribute, rather than separate foreground and
background attributes. Refer to the section Specifying Display
Colors in Chapter 3 for more information.
Writing ~Hi~
In many applications you will want to write part of a string
in one color, and the remainder of the string in another color. For
example, when displaying the text "Are you sure you want to format
the network server?", you might want the words format and network
server to be in a color which makes them stand out clearly. One way
to achieve this would be to write the text using several WriteAt
statements, with a different attribute for each statement. A
slicker way is to use Gold's WriteHi functions.
WriteHi(X,Y,HiFB,FB:byte;Str:string);
WriteHiCenter(Y,HiFB,FB:byte;Str:string);
By embedding tilde characters ( ~ ) in the string, you can
identify which portions of the string are to be written in each
attribute. All characters up to the first tilde are written in the
FB attribute, the text following the first tilde is written in the
HiFB attribute. Thereafter, the attribute switches every time the
tilde is encountered. The tilde characters are not displayed. To
write the server format warning (described earlier) you might use
the following statement:
WriteHi(10,13,LightgrayOnBlue,WhiteOnBlue,
'Are you sure you want to ~format~ the ~network server?');
The concept of embedding tilde characters in strings is
supported throughout Gold. For example, if you add an item to a
pull down menu you can highlight a character by enclosing it within
tildes, e.g. '~W~indow'. If you want to write a string with the
first capital letter in a different color, use WriteCap as follows:
WriteCap(X,Y,FBCap,FB:byte;Str:string);
Run the demo DEMFS1 to see a variety of the screen writing
functions in action.
Erasing Text and Changing Display Colors
The following four procedures can be used to clear all or part of
the text:
Clear(FB:byte; C:Char);
Clears the entire screen or window and fills the area with the
specified character using the specified color.
PartClear(X1,Y1,X2,Y2:byte; FB:byte; C:char);
Similar to Clear, but only clears a specified region of the
screen or window.
ClearLine(Y,FB:integer);
Clears an entire line, i.e. fills the entire line with spaces,
using the specified attribute.
ClearText(X1,Y1,X2,Y2,FB:byte);
Similar to Clearline, but a rectangular section of the screen
or window is cleared.
Writing Non-String Information
One of the great strengths of Turbo Pascal's writeln is its
ability to accept any number of variables of many different types.
Unfortunately, the compiler does not allow third-party developers
to create custom procedures with similar flexibility! There is no
(practical) way around the fact that Gold's screen writing
procedures only support strings. However, if you need to write
other types, you can use the string conversion functions in GOLDSTR
to cast different types to a string. For example, if you want to
write an integer variable to a string you could use the IntToStr
function as follows:
WritePlain(1,1,IntToStr(ClientsAge));
Although you may only pass one string argument to Gold's
screen writing procedures, you can use Turbo Pascal's string
concatenation operators to build a single string argument from
multiple string components. For example, you could display
someone's age with the following concatenated string:
WritePlain(1,1,'Your age is '+IntToStr(ClientsAge));
By using string casting functions and concatenation you can
gain eighty percent of writeln's flexibility and take advantage of
Gold's more powerful string writing procedures. One final thought.
If you frequently write non-string types, you might consider
writing your own procedure which is passed the non-string type and
which, in turn, calls Gold's procedure. For example, the following
procedure could be used to write any integer type:
procedure WriteNumAt(X,Y,Attr: byte; Val:longint);
{}
begin
WriteAT(X,Y,Attr,IntToStr(Val));
end; { WriteNumAt }
You might be wondering why we didn't include a whole family of
procedures in Gold to accommodate all the varied types that you
might need. We decided that 750 procedures was enough already.
Write your own!
Box and Line Drawing
To draw a box on the screen or window, simply call one of the
following procedures:
Box(X1,Y1,X2,Y2,FB,style:byte);
Draws a rectangular box (using the ASCII box drawing
characters) at the specified coordinates in the specified
attribute. The style byte is described below. Note that the
interior of the box is not written -- whatever was on the screen
will remain visible.
FBox(X1,Y1,X2,Y2,FB,style:byte);
Like Box, but the interior of the box is filled.
GrowFBox(X1,Y1,X2,Y2,FB,style:byte);
Like FBox, but the box grows on the screen with a cutesy
exploding effect.
Box3D(X1,Y1,X2,Y2:byte;TLFB,BRFB,Style:byte);
Like FBox, but the upper left and lower right sides are
displayed with different attributes, giving a chiseled or 3-D
effect. (Hey, its not bad for DOS.) The style attribute may have a
value in the range 0 to 9. The box styles correspond with the
window styles used throughout Gold. The appearance of the box is
dependent upon the active character set, i.e. the box styles differ
when custom characters are in use. The following table describes
the supported box styles.
Style Standard Chars Custom Chars
0 No box (spaces) No box (spaces)
1 Single-line Single-line
2 Double-line Single-line
3 No box (spaces) No box (spaces)
4 Single-line Single edge line
5 Two-line menu layout Two-line menu layout
6 Single line on three sides Single line on three sides
7 Single-line chiseled out Single-line chiseled out
8 Single-line chiseled in Single-line chiseled in
9 Special notepad Special notepad
Execute the program DEMFS2.PAS to see the supported box styles.
To draw a single line using the following two functions, use a
Style value of 1 for single lines and 2 for double lines:
HorizLine(X1,X2,Y,FB,Style:byte);
VertLine(X,Y1,Y2,FB,Style:byte);
Use the smart-line drawing functions if you want to join
intersecting lines. They will automatically draw box corners, and T
junctions to join lines together. Cool.
SmartVertLine(X,Y1,Y2,FB,Style:byte);
SmartHorizLine(X1,X2,Y,FB,Style:byte);
Execute the demo file DEMFS3.PAS to see the smart-line
functions in action.
Reading the Display
This section has nothing to do with optometry. If you want to
literally pull characters or attributes from a specific location on
the screen or window, you can use the following functions:
ReadChar(X,Y:byte):char;
Returns the character located at position (X,Y) of the target
screen or window.
ReadAttr(X,Y:byte):byte;
Returns the attribute (or color) at position (X,Y) of the
target screen or window.
ReadWord(X,Y:byte;var Attr:byte; var Ch: char);
Combines the above two functions into a single procedure call.
Customizing Scroll Bar Appearance
Gold uses scroll bars in windows, lists, forms, etc. If you
don't like the default characters used to create the scroll bars
(shame on you), you can call the following procedure to instruct
Gold to use your preferred characters:
SetScrollChars(U,D,L,R,E,B:char);
Defines which characters will be used to draw horizontal and
vertical scroll bars. See the Reference Guide for further details.
If you want to set the characters back to the (superior) Gold
defaults, simply call the procedure SetScrollDefaults.
Call procedures WriteHScrollBar and WriteVScrollBar to
experiment with the scroll bar appearance. See the demo DEMFS4.PAS.
Automatic Line Wrapping
GOLDFAST defines a global variable LineWrap which is used by
the screen and window writing code to control whether Gold
automatically wraps long strings to the next line. By default, line
wrapping is turned off. If you want enable line wrapping, simply
set LineWrap to true as follows:
LineWrap := true;
Understanding Window Coordinates
Normally, Gold uses global screen coordinates (which match the
screen dimensions). For example, the (X,Y) coordinates (5,3)
identify a location five character positions from the left side of
the display and three rows down from the top of the display. Gold
also supports local or window coordinates. When a local window is
set, all screen writing coordinates become relative to the local
window. The following routines provide coordinate support:
SetWindow(X1,Y1,X2,Y2: byte);
ResetWindow;
SetWinIgnore(On:Boolean);
GetSetWinIgnore(On:Boolean):boolean;
Use the procedure SetWindow to limit screen writing within the
specified coordinates. To remove the local window coordinates call
ResetWindow -- this sets the screen writing back to the global
coordinate system.
Even though local window coordinates are set, you can instruct
Gold to ignore them (or not) using the SetWinIgnore function.
Alternatively, call GetSetWinIgnore if you want to record the
ignore state, before temporarily setting it. Having written the
appropriate data, set the coordinate state to its previous setting.
You might use this function, for example, in a hooked procedure
which displays a clock at the top right of the display, as follows:
procedure DisplayTime;
var IgnoreState: boolean;
begin
IgnoreState := GetSetWinIgnore(true);
WriteAT(70,1,0,Time);
SetWinIgnore(IgnoreState);
end; { DisplayTime }
The principles of active window coordinates apply to screens,
virtual screens and windows.
The demo program DEMFS5.PAS illustrates how to manipulate the
window coordinate settings.
Managing Screens
Move Data Around the Screen
The following three procedures manipulate data already visible
on a screen:
CopyScreenBlock(X1,Y1,X2,Y2,X,Y:byte);
Copies text and attributes from one part of the screen to
another. The source and target areas can overlap. The procedure is
passed the upper left and lower right coordinates of the area to
copy and the upper left coordinates of the target area.
MoveScreenBlock(X1,Y1,X2,Y2,X,Y:byte);
This procedure is similar to CopyScreenBlock except the
original source area is erased.
Scroll(Way:gDirection;X1,Y1,X2,Y2:byte);
Scrolls text in a rectangular region of the screen. The data
can be scrolled in any of the following four directions: Up, Down,
Left, Right. One row or column of text is removed, blank characters
are inserted in their place.
Using Virtual Screens
When is a screen not a screen? When it's a virtual screen. A
virtual screen emulates the characteristics of the standard video
memory, but is located on the heap. Virtual screens are used to
save copies of the visible screen, as well as to prepare screens
which can be pushed onto the visible screen in a flash (or with a
sliding special effect).
By default Gold supports five virtual screens. If (for some
bizarre reason) you need more virtual screens, change the
MaxVirtualScreens setting in GOLDFAST to a higher value.
Creating Virtual Screens
To create a virtual screen simply call CreateScreen as
follows:
CreateScreen(Page,W,D,FB:byte);
The page number is a value in the range 1 to MaxVirtualScreens
(see note above). If that page is being used by another virtual
screen, the screen will be overwritten. W and D represent the
screen width and depth, respectively. A virtual screen can be as
large as 255 characters wide by 255 rows deep. The last parameter,
FB, is the default attribute of the newly created screen.
Before writing to a virtual screen you should set the target
focus using the ActivateVirtualScreen procedure (discussed
earlier).
Saving the Visible Screen
By calling SaveScreen you can create a virtual screen (with
the same dimensions as the display) and automatically copy the
visible screen contents to the virtual screen along with the cursor
position and size. Use this function when you want to save the
screen in its entirety to restore it later.
SaveScreen(Page:byte);
Saves the current screen (on the heap) for a subsequent restore.
The only parameter passed is the page or screen number. If a screen
has already been created with the same screen number, the old
screen will be overwritten.
When a virtual screen is created using CreateScreen or
SaveScreen, memory must be allocated on the heap. Always check the
LastFastError function to make sure the screen creation was
successful. If the procedure fails due to a lack of memory, there
are two probable causes.
1 -- There really isn't enough memory.
2 -- The maximum heap available has been restricted by the $M
compiler directive (or the IDE equivalent).
Restoring Screens
The user can only see the contents of a virtual screen when it
is restored to the visible screen. To quickly restore a screen call
the RestoreScreen procedure and identify the page or screen number
of the page to be restored. The virtual screen is not affected by a
restore; you can restore the same screen many times.
If you only want to restore part of a virtual screen, use the
following function:
PartRestoreScreen(Page,X1,Y1,X2,Y2,X,Y:byte);
Restores part of a virtual screen. The procedure is passed the
screen number, the upper-left and lower-right coordinates of the
area of the screen to be restored and the target coordinates for
the top left corner of the area, i.e. part of a saved screen can be
restored to a different location on the visible screen.
For a little more pizzazz you can use a slide.i..n...g effect
when you restore the screen. A little bit of flash goes a long way.
The two slide functions (listed below) accept an additional
argument of type gDirection, which is declared in GOLDFAST as
follows:
gDirection = (Up,Down,Left,Right,Vert,Horiz);
As you might have deduced (Iowans excepted) this argument
controls the direction used to slide the screen onto the display.
SlideRestoreScreen(Page:byte;Way:gDirection);
PartSlideRestoreScreen(Page:byte;Way:gDirection;X1,Y1,X2,Y2:byte);
Disposing of Screens
Virtual screens consume memory (about 4000 bytes per 80 by 25
screen). When you no longer need a virtual screen, you should
dispose of it using the DisposeScreen function, as follows:
DisposeScreen(Page:byte);
Dispose of the memory used to store a virtual screen. If the
specified screen doesn't exist, the procedure is ignored.
Using Condensed Screens
Systems equipped with EGA or VGA displays can support the
display of 43 or 50 lines of text. GOLDFAST includes the following
two procedures to switch between condensed and standard modes.
SetCondensed;
Changes the display to 43 or 50 line mode.
Set25;
Sets the display mode to a standard 25 lines.
The Gold variable HardVars.Depth is set to reflect the number
of display lines.
The mouse cursor will not be aware that the size of the screen
has been altered. Having switched display modes you should call the
mouse function MouseConfine (discussed in the next chapter) to
allow the mouse to navigate the entire visible screen (and no
more).
Run the demo DEMFS6.PAS to see how to set display modes, and
how to adjust the mouse.
Using Prefabricated Windows
Most applications use a set of "standard windows" to interact
with the user, e.g. message windows with some text and an OK
button.
Gold provides a set of prompt procedures and functions which
make it easy to display text in a window. In each case, the
procedure is passed a title and a message, and Gold computes the
appropriate window size and position based on the length and
content of the message text.
For example, the following statement would instruct Gold to
display a window with the title "Yowsa" and the message "What's
happening babe?":
PromptOK('Yowsa','What''s happening babe?');
The user would be presented with the message window containing
the text and a single OK button. Gold automatically calculates the
window dimensions based on the input.
The window style (i.e. box border) can be modified by setting
the value of the variable WinVars.PromptStyle to a value in the
range 1 to 9. The default is style 7.
Gold provides the following prompt procedures and functions:
PromptOK(Tit,Msg:string);
Displays a message in a window with an OK button.
PromptOKCancel(Tit,Msg:string): byte;
Displays the title and message with OK and Cancel buttons. A 1
is returned if OK is selected, and a 2 if Cancel is selected.
PromptYesNo(Tit,Msg:string): byte;
Like PromptOKCancel but the buttons say Yes and No.
PromptCustom(Tit,Msg:string; But1,But2,But3:StrButton;
HK1,HK2,HK3, Default:word; WaitTime:longint): byte;
Displays a custom prompt window with up to three custom
buttons. As well as the title and the message, the function is
passed the text of three buttons (null if the button is not needed)
along with the hotkey for each button and the default. The final
parameter is the wait time in milliseconds -- specify zero if you
want to force the user to make a choice, otherwise the function
will return a zero if the user has not pressed a button before the
wait period has expired.
In addition to the above prompt functions which accept the
message as a single string, there are a corresponding set of
functions which accept string linked lists (discussed in Chapter
13) and are called PromptOKStrSLL, PromptOKCancelStrSLL,
PromptYesNoStrLL, and PromptCustomStrLL. These functions allow you
to display messages longer than 255 characters.
Both the message text and the buttons supported embed "~"
characters to allow two display colors to be used. Also, you can
embed a split vertical bar character "|" in the message string to
force a line break, i.e. all text following the character will be
written to the next line. One final tip: any line commencing with
the "^" character will be automatically centered in the window. All
these special characters are automatically stripped from the
message before it is displayed.
The button strings used in the standard (non-custom) prompt
windows are defined as variables in GOLDWIN as follows:
OKButStr: strButton = ' ~O~K ';
OKHotKey = 280; { Alt+O }
CancelButStr: strButton = '~C~ancel';
CancelHotKey = 302; { Alt+C }
YesButStr: strButton = ' ~Y~es ';
YesHotKey = 277; {Alt-Y}
NoButStr: strButton = ' ~N~o ';
NoHotKey = 305; {Alt-N}
Both the text and the hotkeys can be changed for international
applications.
If you need to display a message longer than 255 characters,
the message can be passed in the form of a string linked list
(discussed in Chapter 13) using the following functions:
PromptOKStrLL(Tit:string;StrLL:StringLL);
PromptOKCancelStrLL(Tit:string;StrLL:StringLL): byte;
PromptYesNoStrLL(Tit:string;StrLL:StringLL): byte;
PromptCustomStrLL(Tit:string; StrLL:StringLL; But1,But2,
But3:StrButton; HK1,HK2,HK3,Default:word;
WaitTime:longint): byte;
Other Gold units provide specialized windows such as forms,
lists, calendars, calculators, file browsers and text editors.
Customizing Display Colors
The colors used by the prompt windows are defined in GOLDTINT.
The following table lists the member name along with the area
affected:
Tint Element Description
PromptBorder1 The color of the border line.
PromptBorder2 The secondary color of the border line
when the style variable
WinVars.PromptStyle is set to 7 or 8.
PromptTitle The color of the title.
PromptBody The color of the window body.
PromptBodyHi The window of the highlighted text in the
window body, i.e. the text after the '~'.
PromptButtonNorm Standard color of the button when the
button doesn't have focus.
PromptButtonNormHot Hi color of the button when the button
doesn't have focus.
PromptButtonHi Standard color of the button when the
button has focus.
PromptButtonHiHot Hi color of the button when the button has
focus.
If you want to use custom display colors, simply change the
appropriate element of the TINT color structure using the
GoldSetcolor procedure. The following code is an extract of
DEMPMT2.PAS:
if ColorScreen then
begin
GoldSetColor(PromptBorder1,LightRedOnRed);
GoldSetColor(PromptBorder2,LightRedOnRed);
GoldSetColor(PromptTitle,WhiteOnRed);
GoldSetColor(PromptBody,LightGrayOnRed);
GoldSetColor(PromptButtonHiHot,WhiteOnMagenta);
GoldSetColor(PromptButtonHi,YellowOnMagenta);
GoldSetColor(PromptButtonNormHot,YellowOnMagenta);
GoldSetColor(PromptButtonNorm,LightgrayOnMagenta);
end;
Run the demos DEMPMT1.PAS to DEMPMT5.PAS to see the prompt
windows in action.
Creating and Managing Custom Windows
If the standard prompt windows (described above) don't meet
your needs, you can create your own custom windows.
Window Principles
Gold supports an infinite number of windows (limited only by
memory). A window has very similar properties to a screen: each
window has a width, each window has a height, a window has an
active cursor position and shape, and within the window there is an
active area which can be written to. In addition to the screen-like
properties, a window has a position, a style (or border design),
and a title.
When you want to display some information in a window, you
should take the following steps:
Decide on the window's dimensions, initial position, and style
(discussed in the next section), then create a window
structure by calling the WinCreate function, e.g.
WinNum := WinCreate(5,5,75,20,4);
The value returned by WinCreate is the logical window number
(or handle) -- the first window will be window 1, etc. This
window handle must be specified in the procedures called in
steps 2 and 3. If WinCreate returns a zero, the window was not
created (probably due to a lack of memory).
Note: Gold has not actually displayed the window at this stage;
behind the scenes a window structure has been created in Gold's
internal window list.
Customize the window characteristics (such as the colors,
title, etc.) using the WinSet... functions, e.g.
WinSetTitle(1,' The Title ');
Display the window by calling WinDisplay, e.g.
WinDisplay(1);
Get input from the user and check to see whether it is a
window-specific keystroke/mouse action by calling the boolean
function IsWinKey. If the function returns true, pass the
keystroke data to the procedure WinProcessKey for processing,
e.g.
GetInput;
if IsWinKey(LastKey,LastX,LastY) then
WinProcessKey(LastKey,LastX,LastY);
Refresh the window contents (having written new data to it) by
calling WinDrawTop or WinDrawAll.
The following code is an extract from DEMWIN1.PAS which
illustrates how to create, display and write to a window:
WinHandle := WinCreate(5,5,75,20,1);
WinSetType(WinHandle,WMove);
WinSetTitle(WinHandle,' My First Window ');
WinDisplay(WinHandle);
WritePlain(1,1,'This .....');
WinDrawAll;
MouseShow(true);
{now process keystrokes}
with KeyVars do
repeat
GetInput;
if IsWinKey(LastKey,LastX,LastY) then
WinProcessKey(LastKey,LastX,LastY);
until (LastKey = 27) or (LastKey = 600);
MouseShow(false);
ResetStartupMode;
Run the program DEMWIN1.PAS to see the code in action.
To summarize, the window management process is: create,
customize, display, handle input, redraw.
Window Styles
A window style controls the format of the window border, i.e.
whether it is single line, double line, etc. Gold supports nine
different window styles -- ten, if you count style 0 which is no
border.
When a window is created (with the WinCreate function) the
last byte parameter identifies the window style, and it should be a
value in the range 0 through 9. These style numbers correspond with
the box styles discussed on page 5-6. As with box styles, window
styles are affected by the use of custom characters (refer to
Chapter 3 for more information).
Run the demo DEMWIN2.PAS to interactively modify the window
styles and see the impact on the window border.
The WinSet... Procedures
After a window has been created, the properties of the windows
can be changed from the defaults by using the following procedures:
WinSetType(Win:integer;W:WinType);
The window type controls which of the window border icons are
active and visible. Windows can be a combination of closeable,
moveable and stretchable. The first parameter identifies which
window will have the type changed, and the second parameter
indicates the new type. WinType is defined (in GOLDWIN) with the
following members:
WinType Description
WPlain No icons.
WClose Close icon.
WMove Close icon and window can be dragged.
WMoveNoClose Window can be dragged but no close icon.
WStretch Window can be stretched, dragged and closed.
WinSetMinSize(Win:integer;Width,Depth: byte);
Defines the minimum size that a user can make a stretchable
window.
WinSetScrollType(Win:integer;S:ScrollType);
Defines whether the window has horizontal and/or vertical
scroll bars. The enumerated type ScrollType is defined in GOLDFAST
with the following members: NoScroll, HorizScroll, VertScroll,
BothScroll.
WinSetColor(Win:integer; A:TintElement;C:byte);
Sets the display color of a specific component (or element) of
the window, e.g. the icons, the frame, the body, etc. See the
section Window Colors (below) for further information.
WinSetShowNum(Win:integer;On:boolean);
Controls whether or not the window number is displayed on the
top right of the window border.
WinSetTitle(Win:integer;Tit:string);
Sets the window title. Set to null to erase a title.
WinSetPosition(Win:integer;NewX,NewY:shortint);
Use this procedure to change the position of the top left
corner of the window.
WinSetStretchProc(Win:integer;S:StretchProc);
During a user actioned window stretch (i.e. when the user is
dragging the lower right window corner) Gold can call a stretch
procedure to provide a way for the application to dynamically
update the window during a stretch operation. Call this procedure
to identify the name of the procedure which will be called as the
window is stretched. Note that the procedure must be declared far
with the following format:
procedure MyProc(X1,Y1,X2,Y2:byte);
Window Shadows
GOLDFAST includes the global variables ShadowType and
ShadowAttr which control the position and color of window shadows.
The shadow attribute may be any value in the range 0 to 255, and
has a default value of 7 (lightgray on black). The following table
identifies the impact of different ShadowType values:
Value Shadow Position
0 Shadows drawn up and to the left.
1 Shadows drawn up and to the right.
2 Shadows drawn down and to the left.
3 Shadows drawn down and to the right.
4 or more No shadow.
Window Colors
For coloring purposes, a window is composed of several
components, each of which may be assigned a different color. The
table below lists the component together with a description.
Component Description
WinBorder The standard window border.
WinBorder3DIn The "in" bump portion of the border for
styles 7 and 8.
WinBorder3DOut The "out" bump portion of the border for
styles 7 and 8.
WinTitle The window title.
WinBody The central part of the window (where text is
written).
WinIcons The close, zoom and stretch icons.
WinCaption The color of the title bar (or caption) when
used in styles 3 and 6 (the Windows emulation
styles).
WinCustom The color used to draw the Microsoft
Windows-style close and zoom icons for window
styles 3 and 6.
WinBorderOff The colors used to draw windows on the
desktop which don't have focus.
There are two additional window colors which were not included
in the table: WinMoveHi and WinMoveBody. These members are used to
define the colors of the message displayed when a user presses
Ctrl-F5 to move a window using the cursor keys.
The default window colors are defined in GOLDTINT; there is
one set for monochrome systems and another for color systems.
To change the display colors for an individual window, you can
call the WinSetColor procedure (discussed earlier) identifying the
window component and the desired color, e.g.
WinSetColor(WinNum,WinBorder,WhiteOnRed);
WinSetColor(WinNum,WinTitle,YellowOnRed);
WinSetColor(WinNum,WinBody,LightgrayOnRed);
WinSetColor(WinNum,WinIcons,LightcyanOnRed);
However, if you want to use a different (non-default) color
scheme for all windows, change the GOLDTINT defaults prior to
creating the windows. Refer to the section Customizing Display
Colors in Chapter 3 for more information.
The Impact of Custom Characters
Gold creates custom characters for line drawing, window icons,
etc. The standard ASCII double line characters are not available
when custom characters are active. If you have custom characters
enabled, and you request a window style which uses double-line
characters (such as style 2) Gold will automatically draw single
lines instead. You can see the effect of the custom characters on
window shapes by running DEMWIN1.PAS and toggling the Custom
Characters check box. Refer to Chapter 3 for more information on
the impact of custom characters on box and border drawing.
Processing Window Input
There are many different user inputs which must be managed in
a custom window: clicking on the various icons, dragging the window
around the screen, stretching the window, double-clicking on the
title, etc. Fortunately, Gold can manage all these inputs and leave
you free to deal with the non-window related keystrokes and mouse
clicks.
The intricacies of managing mouse and keyboard input are
discussed in the next Chapter, but the principles are simple. Any
single user input can be defined with three variables: the
keystroke which is of type word, and two bytes which identify the X
and Y coordinates of the mouse cursor.
Having garnered user input you can test whether the input is a
window action by calling the function IsWinKey which is defined as
follows:
IsWinKey(K:word;KX,KY:byte):boolean;
The function is passed three parameters identifying the
keystroke details and returns true if the keystroke is a window
management keystroke which can be handled automatically by Gold.
If the function returns false, the keystroke is not associated with
a generic window manipulation task (such as zoom or move), and
should be handled by the application's own keyboard handler.
If IsWinKey returns true, call the function WinProcessKey
(defined below) to have Gold process the keystroke and manipulate
the window as necessary.
WinProcessKey(var K:word; var KX,KY:byte);
This procedure is passed the window-related keystroke.
Having processed the keystroke, Gold updates the passed
parameters to indicate what window activity transpired. An
application should evaluate the updated parameters and redraw the
window contents as appropriate. For example, if the window was
stretched, K will be updated with a value of 602, and the values
of X and Y are irrelevant.
The following table identifies the values which can be
assigned to K along with those instances where X and Y also have a
meaning.
Key Explanation
600 The user clicked on the close icon and the window has
been closed.
601 The window was moved or dragged.
602 The window was zoomed or stretched, i.e. resized.
610 The user clicked on the up arrow on the vertical
scrollbar.
611 The user clicked on the down arrow on the vertical
scrollbar.
612 The user clicked on the left arrow on the horizontal
scrollbar.
613 The user clicked on the right arrow on the horizontal
scrollbar.
614 The user clicked along the length of the vertical
scrollbar. X is updated to reflect the number of
characters down the scrollbar where the user clicked,
and Y identifies the length of the scrollbar in
characters.
615 The user clicked along the length of the horizontal
scrollbar. X is updated to reflect the number of
characters along the scrollbar where the user clicked,
and Y identifies the length of the scrollbar in
characters.
The Timing of Window Updates
The code which manages the window kernel is complex and
primarily written in assembly language. So there! However, an
understanding of the general architecture will help you to figure
out when the visible screen is updated. It may also explain some of
the odd behavior that occurs when you are tracing a program using
the debugger.
To allow for updates to fully or partially obscured windows,
Gold maintains a window image off-screen. More often than not, an
application will write several different strings to a window at one
time. When you write to a window, the off-screen image of the
window is immediately updated, but, to avoid unnecessary screen
updates, the window image is not immediately transferred to the
visible screen.
The windows are updated on the visible screen when one of the
following two functions is called:
WinDrawAll;
Forces an update of the screen background and all the windows.
Thanks to the brilliance of the windows code, the user will not
experience any flicker as the windows are updated.
WinDrawTop;
The top-most window is redrawn.
If you want every window update to be automatically displayed
on the visible screen, set the global GOLDFAST variable ShowNow to
true.
Cursor Management
Routines are available for hiding and displaying the cursor as
well as changing the cursor shape from thin to half to full, or to
any other available shape. The cursor routines function on
monochrome and color video systems. As with screen and window
updates, the cursor management functions are specific to the active
window or screen.
Setting the Cursor Shape
The following procedures can be used to set the cursor to one
of four standard shapes:
CursorOff;
Makes the cursor invisible.
CursorOn;
Makes the cursor visible and sets it to the default DOS shape,
i.e. a blinking line at the bottom of the character.
CursorHalf;
Makes the cursor a block filling the lower half of the
character field.
CursorFull;
Makes the cursor a full block filling the entire character
field.
In text mode, an individual character is comprised of a number
of scan lines. Usually the cursor is located on one or two scan
lines near the bottom of the character. Different display systems
use varying numbers of scan lines. For example, a monochrome
display usually has fourteen scan lines, as does an EGA system, but
a CGA only has 8. Use the function CharHeight to return the actual
number of scan lines per character, before using CursorSize to set
the cursor to a custom size.
CharHeight: integer;
Returns the number of scan lines per character used by the
video display system in the current mode.
CursorSize(T,B:byte);
Sets the cursor to the specified top and bottom scan lines.
The top scan line (e.g. the top bar of the letter "T") is scan line
zero. As an example, to set the cursor to a half block filling the
upper half of the screen (on a VGA system), call:
SizeCursor(0,7);
DEMFS8.PAS illustrates the cursor setting procedures.
Setting the Cursor Position
You guessed it, to change the position of the cursor, call
GotoXY and pass the new (X,Y) coordinates of the cursor. Gold's
GotoXY is more sophisticated than Borland's GotoXY. For example, if
you position the cursor in a window in a location that is
physically off screen (because the window has been partially
dragged screen), Gold will automatically make the cursor invisible.
GotoXY(X,Y:byte);
Positions the cursor (using local coordinates) relative to the
active window or screen.
Getting the Cursor Details
The following three routines will return information about the
active window or screen's cursor location and size:
CursorFind(var X,Y,Top,Bot:byte);
Updates the passed parameters with the (X,Y) coordinates of
the cursor, and the cursor's top and bottom scan lines.
WhereX: byte;
Returns the X coordinate position of the cursor.
WhereY: byte;
Returns the Y coordinate position of the cursor.
If you want to manage the cursor using standard global screen
coordinates (ignoring any local coordinates, windows and screens,
etc.), you can use one of the following absolute cursor routines:
AbsGotoXY(X,Y:byte);
AbsWhereXY(var X,Y:byte);
AbsCursorSize(T,B:byte);
Error Management
Some of the GOLDFAST and GOLDWIN functions have the potential
to fail. For example, CreateScreen may have insufficient memory.
The Reference Manual identifies every procedure and function which
may fail and set a non-zero error code. GOLDFAST and GOLDWIN
provide the following two functions to test the success of the last
command:
LastFastError: integer;
LastWinError: integer;
Refer to Chapter 3 for more information on error management.
Other Neat Stuff
Listed below are some additional procedures and functions
which you may find useful:
DrawShadow(X1,Y1,X2,Y2:integer);
Draws a lightgray shadow down and to the right of the
specified coordinates.
Attrib(X1,Y1,X2,Y2,FB:byte);
Changes the display attribute (i.e. color) of a region of the
active screen or window. Note the text in the affected area is not
deleted -- only the color of the text is changed. The procedure is
passed the upper left and lower right (X,Y) coordinates together
with the desired display attribute.
ResetStartUpMode;
Sets the display device to the same mode that was in effect
when the program was executed and automatically removes any custom
characters and replaces them with the standard ASCII character set.